"         __  __        __     _____ __  __ ____   ____
"        |  \/  |_   _  \ \   / /_ _|  \/  |  _ \ / ___|
"        | |\/| | | | |  \ \ / / | || |\/| | |_) | |
"        | |  | | |_| |   \ V /  | || |  | |  _ <| |___
"        |_|  |_|\__, |    \_/  |___|_|  |_|_| \_\\____|
"                |___/


" ===
" === Auto load for first time uses
" ===
if empty(glob('~/.config/nvim/autoload/plug.vim'))
    silent !curl -fLo ~/.config/nvim/autoload/plug.vim --create-dirs
                \ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
    autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif

" ===
" === Plugin On
" ===

filetype on
filetype indent on
filetype plugin on
filetype plugin indent on

" ===
" === Basik mappings
" === Set leader as space

let mapleader = "\<space>"  "设置leader键为空格
map <leader>w :w<CR>
map <leader>q :q<CR>
map <leader>wq :wq<CR>
map <leader>r :source $MYVIMRC<CR>
inoremap Q <Esc>

"Opening a terminal window
noremap <LEADER>/ :set splitbelow<CR>:sp<CR>:term<CR>

map <leader><CR> :nohlsearch<CR>

map <leader>wl :set splitright<CR>:vsplit<CR>
map <leader>wh :set nosplitright<CR>:vsplit<CR>
map <leader>wj :set nosplitbelow<CR>:split<CR>
map <leader>wk :set splitbelow<CR>:split<CR>

map <leader>h  <C-w>h
map <leader>l  <C-w>l
map <leader>j  <C-w>j
map <leader>k  <C-w>k

map <up> :res +5<CR>
map <down> :res -5<CR>
map <left> :vertical resize-5<CR>
map <right> :vertical resize+5<CR>

map <leader>sv <C-w>t<C-w>H
map <leader>sh <C-w>t<C-w>K

map <leader>tu :tabe<CR>
map <leader>tk :-tabnext<CR>
map <leader>tj :+tabnext<CR>



"设置跳出自动补全的括号
func SkipPair()  
    if getline('.')[col('.') - 1] == ')' || getline('.')[col('.') - 1] == ']' || getline('.')[col('.') - 1] == '"' || getline('.')[col('.') - 1] == "'" || getline('.')[col('.') - 1] == '}'  
        return "\<ESC>la"  
    else  
        return "\t"  
    endif  
endfunc  
" 将tab键绑定为跳出括号  
inoremap <F4> <c-r>=SkipPair()<CR>

"设置<F5>自动编译运行当前程序
map <F5> :call CompileRunGcc()<CR>

func! CompileRunGcc()
    exec "w"
    if &filetype == 'c'
        exec '!g++ % -o %<'
        exec '!time ./%<'
    elseif &filetype == 'cpp'
        set splitbelow
        exec "!g++ -std=c++11 % -Wall -o %<"
        "exec '!time ./%<'
        :term ./%<
    elseif &filetype == 'python'
        set splitbelow
        :term python3 %
    elseif &filetype == 'sh'
        :!time bash %
    endif
endfunction


" Themes
set background=dark
let g:SnazzyTransparent =1

" Editor behavior


set autoread

" Copy to system clipboard
vnoremap Y :w !xclip -i -sel c<CR>

syntax enable
syntax on
set spell
set number
set relativenumber
set cursorline
set wrap
set showcmd
set wildmenu
set laststatus=2
set ruler
set history=1000
set foldenable
set foldmethod=manual
set nocompatible
set clipboard+=unnamed
set nobackup
set noswapfile
set hlsearch
set ignorecase
set incsearch
set gdefault                         "行内替换
set mouse=a
set selection=exclusive
set expandtab
set tabstop=4
set shiftwidth=4
set scrolloff=10
set autoindent
set list
set showmatch
" Cursor shape
let &t_SI = "\<Esc>]50;CursorShape=1\x7"
let &t_SR = "\<Esc>]50;CursorShape=2\x7"
let &t_EI = "\<Esc>]50;CursorShape=0\x7"
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
"设置编码,支持中文不乱码
set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936
set termencoding=utf-8
set encoding=utf-8
"设置插入模式下粘贴内容是不会有格式变形、胡乱缩进等问题
set listchars=tab:>-,trail:-


" ===
" === Install Plugins with Vim-Plug
" ===

call plug#begin('~/.vim/plugged')

Plug 'vim-airline/vim-airline'           "底部状态栏
Plug 'vim-airline/vim-airline-themes'
"Plug 'connorholyday/vim-snazzy'           "主题
Plug 'morhetz/gruvbox'
Plug 'dracula/vim', { 'as': 'dracula' }
Plug 'ajmwagar/vim-deus'
Plug 'ayu-theme/ayu-vim'


"General Highlighter
Plug 'jaxbot/semantic-highlight.vim'
Plug 'chrisbra/Colorizer' " Show colors with :ColorHighlight

" File navigation
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
Plug 'Xuyuanp/nerdtree-git-plugin'

"文件树
  Plug 'Shougo/defx.nvim'
  Plug 'roxma/nvim-yarp'
  Plug 'roxma/vim-hug-neovim-rpc'
  Plug 'kristijanhusak/defx-icons'

" Taglist
Plug 'majutsushi/tagbar', { 'on': 'TagbarOpenAutoClose' }

" Error checking
Plug 'w0rp/ale'

" Undo Tree
Plug 'mbbill/undotree/'

" Other visual enhancement
Plug 'mhinz/vim-startify'

" Python
Plug 'vim-scripts/indentpython.vim', { 'for' :['python', 'vim-plug'] }
Plug 'numirias/semshi', {'do':'UpdateRemotePlugins'}
Plug 'tweekmonster/braceless.vim'
Plug 'hdima/python-syntax'
Plug 'tmhedberg/SimpylFold'
Plug 'Vimjas/vim-python-pep8-indent',{'for' :['python','vim-plug']}


" Markdown
Plug 'iamcco/markdown-preview.nvim', { 'do': { -> mkdp#util#install_sync() }, 'for' :['markdown', 'vim-plug'] }
Plug 'dhruvasagar/vim-table-mode', { 'on': 'TableModeToggle' }
Plug 'mzlogin/vim-markdown-toc'
Plug 'vimwiki/vimwiki'
Plug 'itchyny/calendar.vim'

" Bookmarks
Plug 'kshenoy/vim-signature'

" Other useful utilities
Plug 'junegunn/goyo.vim' " distraction free writing mode

"auto-complete
Plug 'neoclide/coc.nvim', {'tag': '*', 'branch': 'release'}

"Formatter
Plug 'Chiel92/vim-autoformat'


" for latex
Plug 'lervag/vimtex'
Plug 'xuhdev/vim-latex-live-preview',{'for': 'tex'}

"Search File Word
Plug 'junegunn/fzf.vim'
Plug 'junegunn/fzf'
Plug 'francoiscabrol/ranger.vim'

Plug 'honza/vim-snippets'         "代码片段
Plug 'Yggdroot/indentLine'        "显示缩进
Plug 'mhinz/vim-startify'         "开始界面
Plug 'kien/rainbow_parentheses.vim' "彩虹括号
Plug 'aperezdc/vim-template'        "文件模板
Plug 'tpope/vim-surround' " type ysks` to wrap the word with '' or type cs'` to change

call plug#end()

" ===
" === Dress up my vim
" ===
set termguicolors " enable true colors support
"colorscheme snazzy
"color dracula
color deus 
"color gruvbox 

hi NonText ctermfg=gray guifg=grey10


" ===
" === NERDTree
" ===
map <leader>ft :NERDTreeToggle<CR>
let NERDTreeMapOpenExpl = ""
let NERDTreeMapUpdir = ""
let NERDTreeMapUpdirKeepOpen = "l"
let NERDTreeMapOpenSplit = ""
let NERDTreeOpenVSplit = ""
let NERDTreeMapActivateNode = "i"
let NERDTreeMapOpenInTab = "o"
let NERDTreeMapPreview = ""
let NERDTreeMapCloseDir = "n"
let NERDTreeMapChangeRoot = "y"


" ==
" == NERDTree-git
" ==
let g:NERDTreeIndicatorMapCustom = {
            \ "Modified"  : "✹",
            \ "Staged"    : "✚",
            \ "Untracked" : "✭",
            \ "Renamed"   : "➜",
            \ "Unmerged"  : "═",
            \ "Deleted"   : "✖",
            \ "Dirty"     : "✗",
            \ "Clean"     : "✔︎",
            \ "Unknown"   : "?"
            \ }

" ===
" === ale
" ===
let b:ale_linters = ['pylint']
let b:ale_fixers = {
            \ 'python':['add_blank_lines_for_python_control_statements','autopep8','isort','yapf',
            \ 'remove_trailing_lines','trim_whitespace'],
            \ 'markdown': ['prettier','remove_trailing_lines','trim_whitespace'],
            \ }


" ===
" === Taglist
" ===
map <silent> T :TagbarOpenAutoClose<CR>


" ===
" === MarkdownPreview
" ===
let g:mkdp_auto_start = 0
let g:mkdp_auto_close = 1
let g:mkdp_refresh_slow = 0
let g:mkdp_command_for_global = 0
let g:mkdp_open_to_the_world = 0
let g:mkdp_open_ip = ''
let g:mkdp_browser = 'chromium'
let g:mkdp_echo_preview_url = 0
let g:mkdp_browserfunc = ''
let g:mkdp_preview_options = {
            \ 'mkit': {},
            \ 'katex': {},
            \ 'uml': {},
            \ 'maid': {},
            \ 'disable_sync_scroll': 0,
            \ 'sync_scroll_type': 'middle',
            \ 'hide_yaml_meta': 1
            \ }
let g:mkdp_markdown_css = ''
let g:mkdp_highlight_css = ''
let g:mkdp_port = ''
let g:mkdp_page_title = '「${name}」'
nmap <leader>md <Plug>MarkdownPreview
nmap <leader>c :set conceallevel=0<CR>
" My snippets for markdown
source ~/.vim/snippits.vim

" ===
" === Markdown-Toc
" ===
let g:vmt_cycle_list_item_markers = 1
nmap <leader>mt :GenTocRedcarpet <CR>


" ===
" === vim-table-mode
" ===
map <LEADER>tm :TableModeToggle<CR>

" ===
" === Vimwiki
" ===
let g:vimwiki_list = [{'path': '~/Work/vimwiki/',
            \ 'ext': '.markdown', 'syntax': 'markdown'}]
map <A-Space> <Plug>VimwikiToggleListItem
let g:vimwiki_table_mappings = 0
let g:vimwiki_global_ext = 0
map <LEADER>t :VimwikiTable<CR>
let g:vimwiki_use_calendar = 1

" ===
"=== Python-syntax
" ===
let g:python_highlight_all = 1
" let g:python_slow_sync = 0


" ===
" === vim-indent-guide
" ===
let g:indent_guides_guide_size = 1
let g:indent_guides_start_level = 2
let g:indent_guides_enable_on_vim_startup = 1
let g:indent_guides_color_change_percent = 1
silent! unmap <LEADER>ig
autocmd WinEnter * silent! unmap <LEADER>ig



" ===
" === Goyo
" ===
map <LEADER>gy :Goyo<CR>


" ===
" === vim-signiture
" ===
let g:SignatureMap = {
            \ 'Leader'             :  "m",
            \ 'PlaceNextMark'      :  "m,",
            \ 'ToggleMarkAtLine'   :  "m.",
            \ 'PurgeMarksAtLine'   :  "dm-",
            \ 'DeleteMark'         :  "dm",
            \ 'PurgeMarks'         :  "dm/",
            \ 'PurgeMarkers'       :  "dm?",
            \ 'GotoNextLineAlpha'  :  "m<LEADER>",
            \ 'GotoPrevLineAlpha'  :  "",
            \ 'GotoNextSpotAlpha'  :  "m<LEADER>",
            \ 'GotoPrevSpotAlpha'  :  "",
            \ 'GotoNextLineByPos'  :  "",
            \ 'GotoPrevLineByPos'  :  "",
            \ 'GotoNextSpotByPos'  :  "mn",
            \ 'GotoPrevSpotByPos'  :  "mp",
            \ 'GotoNextMarker'     :  "",
            \ 'GotoPrevMarker'     :  "",
            \ 'GotoNextMarkerAny'  :  "",
            \ 'GotoPrevMarkerAny'  :  "",
            \ 'ListLocalMarks'     :  "m/",
            \ 'ListLocalMarkers'   :  "m?"
            \ }


" ===
" === Undotree
" ===
let g:undotree_DiffAutoOpen = 0
map <leader>L :UndotreeToggle<CR>



"airline配置
"Automatically displays all buffers when there's only one tab open
let g:airline#extensions#tabline#enabled = 1
"Separators can be configured independently for the tabline, so here is how you can define "straight" tabs:
let g:airline#extensions#tabline#left_sep = ' '
let g:airline#extensions#tabline#left_alt_sep = '|'
let g:airline#extensions#tabline#formatter = 'unique_tail'

"airline_theme
let g:airline_theme='angr'


"coc.nvim
"To support completion trigger on insert enter
" Installing plugins
let g:coc_global_extensions = ['coc-python', 'coc-vimlsp', 'coc-snippets',
            \'coc-emmet', 'coc-html', 'coc-json', 'coc-css', 'coc-tsserver', 'coc-yank',
            \'coc-lists', 'coc-gitignore','coc-texlab','coc-imselect',
            \'coc-prettier','coc-highlight','coc-pairs' ]
"use <tab> for trigger completion and navigate to the next complete item
function! s:check_back_space() abort
    let col = col('.') - 1
    return !col || getline('.')[col - 1] =~ '\s'
endfunction

inoremap <silent><expr> <Tab>
            \ pumvisible() ? "\<C-n>" :
            \<SID>check_back_space() ? "\<Tab>" :
            \coc#refresh()

" Useful commands
nnoremap <silent> <space>y  :<C-u>CocList -A --normal yank<cr>
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)
nmap <leader>rn <Plug>(coc-rename)

" ===
" === coc.snippets
" ===
inoremap <silent><expr> <TAB>
            \ pumvisible() ? coc#_select_confirm() :
            \ coc#expandableOrJumpable() ? "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
            \ <SID>check_back_space() ? "\<TAB>" :
            \ coc#refresh()

function! s:check_back_space() abort
    let col = col('.') - 1
    return !col || getline('.')[col - 1]  =~# '\s'
endfunction

let g:coc_snippet_next = '<tab>'





" ===
" === indentLine
" ===
let g:indentLine_char = '│'
let g:indentLine_color_term = 238
let g:indentLine_color_gui = '#333333'
silent! unmap <LEADER>ig
autocmd WinEnter * silent! unmap <LEADER>ig


" ===
" === vimtex
" ===
let g:tex_flavor='latex'
let g:vimtex_view_method='zathura'
let g:livepreview_previewer = 'okular'
let g:vimtex_quickfix_open_on_warning = 0
let g:vimtex_quickfix_mode=0
let g:Tex_CompileRule_pdf = 'xelatex -src-specials -synctex=1 -interaction=nonstopmode $*'
let g:vimtex_view_general_options_latexmk = '-reuse-instance'
let g:vimtex_view_general_options = '-reuse-instance -forward-search @tex @line @pdf'
"隐藏功能，除光标所在行，文本中的LaTeX代码会隐藏
set conceallevel=1
let g:tex_conceal='abdmg'
map <LEADER>lc :VimtexCompile <CR>

" ===
" === 彩虹括号
" ===
let g:rbpt_colorpairs = [
            \ ['brown',       'RoyalBlue3'],
            \ ['Darkblue',    'SeaGreen3'],
            \ ['darkgray',    'DarkOrchid3'],
            \ ['darkgreen',   'firebrick3'],
            \ ['darkcyan',    'RoyalBlue3'],
            \ ['darkred',     'SeaGreen3'],
            \ ['darkmagenta', 'DarkOrchid3'],
            \ ['brown',       'firebrick3'],
            \ ['gray',        'RoyalBlue3'],
            \ ['darkmagenta', 'DarkOrchid3'],
            \ ['Darkblue',    'firebrick3'],
            \ ['darkgreen',   'RoyalBlue3'],
            \ ['darkcyan',    'SeaGreen3'],
            \ ['darkred',     'DarkOrchid3'],
            \ ['red',         'firebrick3'],
            \ ]

let g:rbpt_max = 16
let g:rbpt_loadcmd_toggle = 0
au VimEnter * RainbowParenthesesToggle
au Syntax * RainbowParenthesesLoadRound
au Syntax * RainbowParenthesesLoadSquare
au Syntax * RainbowParenthesesLoadBraces



" ===
" === FZF
" ===
map <C-p> :FZF<CR>

" ===
" === Ranger.vim
" ===
nnoremap <leader>R :Ranger<CR>

" ===
" === fzf-gitignore
" ===
map <LEADER>gi <Plug>(fzf-gitignore)


" ===
" === Ranger.vim
" ===
 nnoremap <LEADER>af :Autoformat<CR>


" ===
" === defx.nvim
" ===
call defx#custom#option('_', {
      \ 'winwidth': 30,
      \ 'split': 'vertical',
      \ 'direction': 'topleft',
      \ 'show_ignored_files': 0,
      \ 'buffer_name': '',
      \ 'toggle': 1,
      \ 'resume': 1
      \ })
nmap <silent> <LEADER>d :Defx <CR>

autocmd FileType defx call s:defx_mappings()

function! s:defx_mappings() abort
  nnoremap <silent><buffer><expr> l     <SID>defx_toggle_tree()                    " 打开或者关闭文件夹，文件
  nnoremap <silent><buffer><expr> .     defx#do_action('toggle_ignored_files')     " 显示隐藏文件
  nnoremap <silent><buffer><expr> <C-r>  defx#do_action('redraw')
endfunction

function! s:defx_toggle_tree() abort
    " Open current file, or toggle directory expand/collapse
    if defx#is_directory()
        return defx#do_action('open_or_close_tree')
    endif
    return defx#do_action('multi', ['drop'])
endfunction
